const axios = require('axios');
const FormData = require('form-data');
const fs = require('fs');
const path = require('path');

// 测试配置
const BASE_URL = 'http://localhost:3000/api/admin';
const ADMIN_USERNAME = 'admin'; // 默认管理员用户名
const ADMIN_PASSWORD = 'admin123'; // 默认管理员密码，从数据库模型中获取

// 生成测试图片
function generateTestImage() {
  const imagePath = path.join(__dirname, 'test_image.png');
  
  // 创建一个简单的红色PNG图片
  const pngHeader = Buffer.from([
    0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, // PNG签名
    0x00, 0x00, 0x00, 0x0D, 0x49, 0x48, 0x44, 0x52, // IHDR块
    0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, // 宽度高度各64像素
    0x08, 0x02, 0x00, 0x00, 0x00, 0xA0, 0x7A, 0xBE, // 颜色类型等
    0x90, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, // IDAT块开始
    0x42, 0x00, 0xAE, 0xCE, 0x1C, 0xE9, 0x00, 0x00, // 红色数据
    0x00, 0x06, 0x74, 0x52, 0x4E, 0x53, 0x00, 0x00, // tRNS块
    0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, // 透明度数据
    0x49, 0x45, 0x4E, 0x44, 0xAE, 0x42, 0x60, 0x82  // IEND块
  ]);
  
  fs.writeFileSync(imagePath, pngHeader);
  return imagePath;
}

// 登录获取token
async function login() {
  try {
    const response = await axios.post(`${BASE_URL}/login`, {
      username: ADMIN_USERNAME,
      password: ADMIN_PASSWORD
    });
    
    if (response.data.success) {
      console.log('登录成功');
      return response.data.token;
    } else {
      console.error('登录失败:', response.data.message);
      return null;
    }
  } catch (error) {
    console.error('登录请求失败:', error.message);
    return null;
  }
}

// 测试创建商品（带图片上传）
async function testCreateGoodsWithImage(token) {
  try {
    const testImagePath = generateTestImage();
    const formData = new FormData();
    
    // 添加商品数据（使用与后端模型匹配的字段名）
    formData.append('title', '测试商品');
    formData.append('price', 99.99);
    formData.append('description', '这是一个带图片的测试商品');
    formData.append('tag', '测试标签');
    formData.append('details', '这是商品的详细介绍内容');
    formData.append('specifications', JSON.stringify([{name: '颜色', value: '红色'}]));
    
    // 添加图片文件
    formData.append('image', fs.createReadStream(testImagePath));
    
    const response = await axios.post(`${BASE_URL}/goods`, formData, {
      headers: {
        'Authorization': `Bearer ${token}`,
        ...formData.getHeaders()
      }
    });
    
    console.log('创建商品成功:', response.data);
    
    // 清理测试图片文件
    fs.unlinkSync(testImagePath);
    
    return response.data.data;
  } catch (error) {
    console.error('创建商品失败:', error.message);
    return null;
  }
}

// 测试更新商品（带图片上传）
async function testUpdateGoodsWithImage(token, goodsId) {
  try {
    const testImagePath = generateTestImage();
    const formData = new FormData();
    
    // 更新商品数据（使用与后端模型匹配的字段名）
    formData.append('title', '更新后的测试商品');
    formData.append('price', 88.88);
    formData.append('description', '这是一个更新后的带图片的测试商品');
    formData.append('tag', '更新标签');
    formData.append('details', '这是更新后的商品详细介绍内容');
    formData.append('image', fs.createReadStream(testImagePath));
    
    const response = await axios.put(`${BASE_URL}/goods/${goodsId}`, formData, {
      headers: {
        'Authorization': `Bearer ${token}`,
        ...formData.getHeaders()
      }
    });
    
    console.log('更新商品成功:', response.data);
    
    // 清理测试图片文件
    fs.unlinkSync(testImagePath);
    
    return response.data.data;
  } catch (error) {
    console.error('更新商品失败:', error.message);
    return null;
  }
}

// 主测试函数
async function runTests() {
  console.log('开始测试商品图片上传功能...');
  
  // 1. 登录获取token
  const token = await login();
  if (!token) {
    console.error('无法获取token，测试终止');
    return;
  }
  
  // 2. 测试创建商品带图片
  const createdGoods = await testCreateGoodsWithImage(token);
  if (!createdGoods) {
    console.error('创建商品失败，测试终止');
    return;
  }
  
  console.log('商品图片路径:', createdGoods.image);
  
  // 3. 测试更新商品带图片
  const updatedGoods = await testUpdateGoodsWithImage(token, createdGoods.id);
  if (!updatedGoods) {
    console.error('更新商品失败，测试终止');
    return;
  }
  
  console.log('更新后的商品图片路径:', updatedGoods.image);
  console.log('所有测试完成！');
}

// 运行测试
runTests();